#include "vector2.h"

#include <math.h>
#include <stdio.h>

//Funciones de la clase

Vector2::Vector2():x(0),y(0)
{
}

Vector2::Vector2(const REAL ax,const REAL ay):x(ax),y(ay)
{
}

Vector2::Vector2(const Vector2 &v):x(v.x),y(v.y)
{
}

REAL Vector2::getX()const
{
  return x;
}

REAL Vector2::getY()const
{
  return y;
}

void Vector2::set(const REAL ax,const REAL ay)
{
  x=ax;
  y=ay;
}

void Vector2::setPolar(const REAL module,const REAL angle)
{
  x=module*cos(angle);
  y=module*sin(angle);
}

void Vector2::setX(const REAL ax)
{
  x=ax;
}

void Vector2::setY(const REAL ay)
{
  y=ay;
}

REAL Vector2::getModule()const
{
  return sqrt(x*x+y*y);
}

REAL Vector2::getAngle()const
{
  return atan2(y,x);
}

void Vector2::setModule(const REAL m)
{
  Vector2 aux=*this;
  x=m*(aux.x/aux.getModule());
  y=m*(aux.y/aux.getModule());
}

void Vector2::setAngle(const REAL a)
{
  REAL m=getModule();
  x=m*cos(a);
  y=m*sin(a);
}

Vector2 Vector2::operator+(const Vector2 &v)const
{
  return Vector2(x+v.x,y+v.y);
}

Vector2 Vector2::operator-(const Vector2 &v)const
{
  return Vector2(x-v.x,y-v.y);
}

Vector2 Vector2::operator*(const REAL k)const
{
  return Vector2(x*k,y*k);
}

bool Vector2::operator==(const Vector2 &v)const
{
  return (x==v.x)&&(y==v.y);
}

bool Vector2::operator!=(const Vector2 &v)const
{
  return (x!=v.x)||(y!=v.y);
}

Vector2 Vector2::operator-()
{
  x=-x;
  y=-y;
  return *this;
}


// Funciones externas a la clase
std::ostream& operator<<(std::ostream& out,const Vector2& v)
{
  out<<"Vector2("<<v.getX()<<","<<v.getY()<<")";
  return out;
}

std::istream& operator>>(std::istream& in,Vector2& v)
{
  REAL ax,ay;
  in.ignore(8);
  in>>ax;
  in.ignore(1);
  in>>ay;
  in.ignore();
  if(in.good())
  {
    v.x=ax;
    v.y=ay;
  }

  return in;
}

Vector2 add(const Vector2 &a,const Vector2 &b)
{
	return Vector2(a.getX()+b.getX(),a.getY()+b.getY());
}

Vector2 sub(const Vector2 &a,const Vector2 &b)
{
	return Vector2(a.getX()-b.getX(),a.getY()-b.getY());
}

REAL dotProduct(const Vector2 &a,const Vector2 &b)
{
	return a.getX()*b.getX()+a.getY()*b.getY();
}

Vector2 multiply(const Vector2 &v,const REAL &k)
{
	return Vector2(v.getX()*k,v.getY()*k);
}

Vector2 multiply(const REAL &k,const Vector2 &v)
{
	return multiply(v,k);
}

Vector2 normalize(const Vector2 &v)
{
	return Vector2(v.getX()/v.getModule(),v.getY()/v.getModule());
}

Vector2 reflect(const Vector2 &v,const Vector2 &n)
{
	Vector2 aux=normalize(n);
	REAL proyection=dotProduct(v,aux);
	aux=multiply(proyection,aux);
	Vector2 resta=sub(aux,v);
	return add(v,multiply(2,resta));
}

Vector2 reverse(const Vector2 &v)
{
	return multiply(-1,v);
}

Vector2 rotateRight(const Vector2 &v)
{
	return Vector2(-v.getY(),v.getX());
}

Vector2 rotateLeft(const Vector2 &v)
{
	return Vector2(v.getY(),-v.getX());
}
